package com.jingyanzi.privilege.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jingyanzi.privilege.service.impl.BaseServiceImpl;
import com.jingyanzi.privilege.dao.SecurityDataaccessMapper;
import com.jingyanzi.privilege.dao.SecurityRoledataaccessMapper;
import com.jingyanzi.privilege.domain.DataAccessDO;
import com.jingyanzi.privilege.domain.DataAccessRoleDO;
import com.jingyanzi.privilege.domain.EmployeeDO;
import com.jingyanzi.privilege.domain.MenuDO;
import com.jingyanzi.privilege.domain.RoleUserDO;
import com.jingyanzi.privilege.domain.result.ResultDO;
import com.jingyanzi.privilege.domain.result.ResultSupport;
import com.jingyanzi.privilege.entity.SecurityDataaccess;
import com.jingyanzi.privilege.entity.SecurityDataaccessExample;
import com.jingyanzi.privilege.entity.SecurityRoledataaccess;
import com.jingyanzi.privilege.entity.SecurityRoledataaccessExample;
import com.jingyanzi.privilege.query.EmployeeQueryDO;
import com.jingyanzi.privilege.service.IDataAccessService;
import com.jingyanzi.privilege.service.IEmployeeService;
import com.jingyanzi.privilege.service.IMenuService;

@Service("dataAccessService")
public class DataAccessServiceImpl extends BaseServiceImpl implements IDataAccessService {
	
	
	private static Logger logger = Logger.getLogger(DataAccessServiceImpl.class);
	
	@Autowired
	private SecurityDataaccessMapper dataaccessMapper;
	
	@Autowired
	private SecurityRoledataaccessMapper roledataaccessMapper;
	
	@Autowired
	private IEmployeeService employeeService;
	
	@Autowired
	private IMenuService menuService;
	
	
	private static Map<Integer, Map<Integer, Map<Integer, List<Integer>>>> employeeDataAccessCache = new HashMap<Integer, Map<Integer, Map<Integer, List<Integer>>>>();

	@Override
	public ResultDO modifi(DataAccessDO domain) {
		ResultSupport result = new ResultSupport();
		SecurityRoledataaccess roleDataAccess = new SecurityRoledataaccess();
		int r = -1;
		r = removeMapping(domain.getRoleId());
		for(Integer id : domain.getDataRoleIds()) {
			
			if(domain.getRoleId() != null) {
				
				roleDataAccess.setRoleId(domain.getRoleId());
				roleDataAccess.setDataAccessId(id);
				
				try {
					roledataaccessMapper.insertSelective(roleDataAccess);
				} catch (Exception e) {
					e.printStackTrace();
					result.setErrorCode(ResultDO.BTN_ADD_ERROR);
					result.setErrorMsg("添加数据视图与角色关联失败");
					result.setSuccess(false);
					return result;
				}
			}
		
		}
		return result;
	}
	
	private int removeMapping(Integer roleId) {
		SecurityRoledataaccessExample example = new SecurityRoledataaccessExample();
		example.createCriteria().andRoleIdEqualTo(roleId);
		try {
			roledataaccessMapper.deleteByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
		return 1;
	}

	@Override
	public ResultDO getDataAccessForMenuId(Integer menuId) {
		
		ResultSupport result = new ResultSupport();
		
		SecurityDataaccessExample example = new SecurityDataaccessExample();
		example.createCriteria().andMenuIdEqualTo(menuId);
	
		List<SecurityDataaccess> list = null;
		
		try {
			list = dataaccessMapper.selectByExample(example);
		} catch(Exception e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.BTN_ADD_ERROR);
			result.setErrorMsg("修改数据视图失败");
			result.setSuccess(false);
			return result;
		}
		
	
		result.setModel(ResultSupport.FIRST_MODEL_KEY, getDataAccessDOList(list));
		return result;
	}
	
	@Override
	public ResultDO getDataAccessForRoleId(Integer roleId) {
		
		ResultSupport result = new ResultSupport();
		
		SecurityRoledataaccessExample example = new SecurityRoledataaccessExample();
		example.createCriteria().andRoleIdEqualTo(roleId);
		
		List<DataAccessRoleDO> daList = new ArrayList<DataAccessRoleDO>();
	
		List<DataAccessDO> doList = new ArrayList<DataAccessDO>();
		
		List<SecurityRoledataaccess> list = new ArrayList<SecurityRoledataaccess>();
		
		try {
			list = roledataaccessMapper.selectByExample(example);
		} catch(Exception e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.BTN_ADD_ERROR);
			result.setErrorMsg("修改数据视图失败");
			result.setSuccess(false);
			return result;
		}
		
		
		SecurityDataaccessExample example2 = new SecurityDataaccessExample();
		
		List<SecurityDataaccess> list2 = null;
		
		try {
			list2 = dataaccessMapper.selectByExample(example2);
		} catch(Exception e) {
			e.printStackTrace();
			result.setErrorCode(ResultDO.BTN_ADD_ERROR);
			result.setErrorMsg("修改数据视图失败");
			result.setSuccess(false);
			return result;
		}
		Integer menuId = 0;
		for(SecurityDataaccess da : list2) {
			DataAccessDO daDO = getDataAccessDO(da);
			for(SecurityRoledataaccess rda : list) {
				if(da.getId().intValue() == rda.getDataAccessId().intValue()) {
					daDO.setIsCheck(1);
				}
				if(da.getType().intValue() == 1) {
					daDO.setIsDisable(1);
				}
			}
			if(menuId.intValue() != da.getMenuId().intValue()) {
				DataAccessRoleDO dataAccessRoleDO = new DataAccessRoleDO();
				ResultDO res = menuService.get(daDO.getMenuId());
				if(!res.isSuccess()) {
					result.setErrorCode(ResultDO.BTN_ADD_ERROR);
					result.setErrorMsg("修改数据视图失败");
					result.setSuccess(false);
					return result; 
				}
				MenuDO menuDO = (MenuDO) res.getModel(ResultSupport.FIRST_MODEL_KEY);
				dataAccessRoleDO.setMenuId(menuDO.getId());
				dataAccessRoleDO.setName(menuDO.getName());
				dataAccessRoleDO.setDataRole(doList);
				daList.add(dataAccessRoleDO);
				menuId = da.getMenuId().intValue();
			}
			doList.add(daDO);
		}
		
		result.setModel(ResultSupport.FIRST_MODEL_KEY, daList);
		return result;
	}
	
	public ResultDO getDataAccessForUserId(DataAccessDO dataAccessDO) {
		
		ResultSupport result = new ResultSupport();
	
		ResultDO res = employeeService.getRole(dataAccessDO.getUid());
		
		if(!res.isSuccess()) {
			result.setSuccess(false);
			return result;
		}
		List<DataAccessDO> doList = new ArrayList<DataAccessDO>();
		
		List<RoleUserDO> roleListDO = (List<RoleUserDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY);
		
		for(RoleUserDO roleUserDO : roleListDO) {
			SecurityRoledataaccessExample example = new SecurityRoledataaccessExample();
			example.createCriteria().andRoleIdEqualTo(roleUserDO.getRoleId());
			
			List<SecurityRoledataaccess> list = new ArrayList<SecurityRoledataaccess>();
			
			try {
				list = roledataaccessMapper.selectByExample(example);
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			for(SecurityRoledataaccess sa : list) {
				logger.info(sa + ": menuId " + dataAccessDO.getMenuId());
				SecurityDataaccessExample example2 = new SecurityDataaccessExample();
				example2.createCriteria().andMenuIdEqualTo(dataAccessDO.getMenuId()).andIdEqualTo(sa.getDataAccessId());
				List<SecurityDataaccess> list2 = null;
				
				try {
					list2 = dataaccessMapper.selectByExample(example2);
					System.out.println(list2);
				} catch(Exception e) {
					e.printStackTrace();
					result.setErrorCode(ResultDO.BTN_ADD_ERROR);
					result.setErrorMsg("修改数据视图失败");
					result.setSuccess(false);
					return result;
				}
				doList.addAll(getDataAccessDOList(list2));
			}
		
		}
		System.out.println("dddd" + doList.size());
		result.setModel(ResultSupport.FIRST_MODEL_KEY, doList);
		return result;
	}
	
	public ResultDO getDataAccessForUserId(Integer uid) {
		
		ResultSupport result = new ResultSupport();
	
		ResultDO res = employeeService.getRole(uid);
		
		if(!res.isSuccess()) {
			result.setSuccess(false);
			return result;
		}
		List<DataAccessDO> doList = new ArrayList<DataAccessDO>();
		
		List<RoleUserDO> roleListDO = (List<RoleUserDO>) res.getModel(ResultSupport.FIRST_MODEL_KEY);
		
		for(RoleUserDO roleUserDO : roleListDO) {
			SecurityRoledataaccessExample example = new SecurityRoledataaccessExample();
			example.createCriteria().andRoleIdEqualTo(roleUserDO.getRoleId());
			
			List<SecurityRoledataaccess> list = new ArrayList<SecurityRoledataaccess>();
			
			try {
				list = roledataaccessMapper.selectByExample(example);
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			for(SecurityRoledataaccess sa : list) {
			
				SecurityDataaccessExample example2 = new SecurityDataaccessExample();
				example2.createCriteria().andIdEqualTo(sa.getId());
				List<SecurityDataaccess> list2 = null;
				
				try {
					list2 = dataaccessMapper.selectByExample(example2);
				} catch(Exception e) {
					e.printStackTrace();
					result.setErrorCode(ResultDO.BTN_ADD_ERROR);
					result.setErrorMsg("修改数据视图失败");
					result.setSuccess(false);
					return result;
				}
				doList.addAll(getDataAccessDOList(list2));
			}
		
		}
		result.setModel(ResultSupport.FIRST_MODEL_KEY, doList);
		return result;
	}

	
	
	public List<Integer> getDataAccess(DataAccessDO dataAccessDO) {
		
		List<Integer> inList = new ArrayList<Integer>();
	
		EmployeeDO employeeDO = getEmployeeDO(dataAccessDO.getUid());
		List<Integer> idList = new ArrayList<Integer>();
		for(Integer id : dataAccessDO.getDataRoleIds()) {
			
			SecurityDataaccess da = null;
			try {
				da = dataaccessMapper.selectByPrimaryKey(id);
			} catch(Exception e) {
				e.printStackTrace();
				
			}
			System.out.println("TYPE:" + da.getType());
			
			ResultDO res = null;
			
			if(da.getType() == 5) {
				return null;
			} else {
				if(da.getType() == 4) {	
					EmployeeQueryDO query = new EmployeeQueryDO();
					query.setCode(employeeDO.getCode());
					query.setPage(false);
					query.setCheckCashier(0);
					//调用下属部门，获得本部门与下属部门所有人的ID
					res = employeeService.queryEmployeeByCode(query);
					List<EmployeeDO> emList = (List<EmployeeDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
					for(EmployeeDO em : emList) {
						idList.add(em.getId());
					}
					
				} 
				if(da.getType() == 3) {
					EmployeeQueryDO query = new EmployeeQueryDO();
					query.setOrgId(employeeDO.getOrgId());
					query.setPage(false);
					query.setCheckCashier(0);
					//调用下属部门，获得本部门有人的ID
					res = employeeService.queryEmployee(query);
					List<EmployeeDO> emList = (List<EmployeeDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
					for(EmployeeDO em : emList) {
						idList.add(em.getId());
					}
					
				}  
				if(da.getType() == 1) {
					//自己的ID
					idList.add(dataAccessDO.getUid());
				}
			}
			
			inList.addAll(idList); 
			
		}
		logger.info("query in ids:" + inList);
		return idList;
	}
	
	/*public void initUserDataAccess(Integer uid) {
		
		Map<Integer, List<Integer>> userDataAccessMap = new HashMap<Integer, List<Integer>>();
		
		Map<Integer, Map<Integer, List<Integer>>> menuDataAccessMap = new HashMap<Integer, Map<Integer, List<Integer>>>();
		
		ResultDO res = getDataAccessForUserId(uid);
		List<DataAccessDO> dataAccessList = (List<DataAccessDO>) res.getModel(ResultDO.FIRST_MODEL_KEY); 
		
		Integer menuId = 0;
		for(DataAccessDO da : dataAccessList) {
			System.out.println(da);
			List<Integer> idList = new ArrayList<Integer>();
			EmployeeDO employeeDO = getEmployeeDO(uid);
			
			logger.info("---------------uid:" + uid + " dataAccess :" + da);
			if(da.getType() == 4) {
				
				EmployeeQueryDO query = new EmployeeQueryDO();
				query.setCode(employeeDO.getCode());
				query.setPage(false);
				query.setCheckCashier(0);
				//调用下属部门，获得本部门与下属部门所有人的ID
				res = employeeService.queryEmployeeByCode(query);
				List<EmployeeDO> emList = (List<EmployeeDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
				for(EmployeeDO em : emList) {
					idList.add(em.getId());
				}
				
			} 
			if(da.getType() == 3) {
				
				EmployeeQueryDO query = new EmployeeQueryDO();
				query.setOrgId(employeeDO.getOrgId());
				query.setPage(false);
				query.setCheckCashier(0);
				//调用下属部门，获得本部门有人的ID
				res = employeeService.queryEmployee(query);
				List<EmployeeDO> emList = (List<EmployeeDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
				for(EmployeeDO em : emList) {
					idList.add(em.getId());
				}
				
			} 
			if(da.getType() == 1) {
				//自己的ID
				idList.add(uid);
			}
			
			userDataAccessMap.put(da.getType(), idList);
			
			if(menuId != da.getMenuId()) {
				menuDataAccessMap.put(da.getMenuId(), userDataAccessMap);
				menuId = da.getMenuId();
			}
			idList.clear();
			idList = null;
		}
		employeeDataAccessCache.put(uid, menuDataAccessMap);
		
	}*/
	
	private EmployeeDO getEmployeeDO(Integer uid) {
		ResultDO res =  employeeService.getEmployee(uid);
		EmployeeDO employeeDO = (EmployeeDO) res.getModel(ResultDO.FIRST_MODEL_KEY);
		return employeeDO;
	}
	
	/*class DataAccessThread implements Runnable {

		@Override
		public void run() {
			while(!Thread.interrupted()) {
				logger.info("___________________ Refresh User Data access__________________");
				for(Integer uid : employeeDataAccessCache.keySet()) {
					initUserDataAccess(uid);
					logger.info("___________________ handler uid:" + uid + "__________________");
				}
				try {
					Thread.sleep(10 * 60 * 1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
					Thread.currentThread().interrupt();
				}
			}
		}
		
	}*/
	
	/*public Runnable createDataAccessThread() {
		return new DataAccessThread();
	}*/


}
